﻿using System;
using System.Windows;
using Kiva7.Transitions;
using Microsoft.Phone.Controls;

using Kiva7.Utilities;
using System.Collections.Generic;
using Microsoft.Phone.Shell;
using Kiva7.Translations;
using Kiva7.Images;

namespace Kiva7.Controls
{
    public class PhoneDetailPageInt : PhoneDetailPage<int>
    {
        protected override int ConvertId(string id)
        {
            int idInt;
            if (int.TryParse(id, out idInt))
            {
                return idInt;
            }
            return -1;
        }
    }

    public class PhoneDetailPageString : PhoneDetailPage<string>
    {
        protected override string ConvertId(string id)
        {
            return id;
        }
    }


    public abstract class PhoneDetailPage<T> : BasePhoneApplicationPage
    {
// ReSharper disable EmptyConstructor
        protected PhoneDetailPage()
// ReSharper restore EmptyConstructor
        {
            
        }

        protected const string IndexKey = "Index";
        protected const string CacheGuidKey = "CacheGuid";
        private Pivot _pivot;

        protected void SetPivot(Pivot pivot)
        {
            _pivot = pivot;
        }

        protected override void CreateApplicationBar()
        {
            AddBarButton(AppResources.Back, ImageUrls.Back, BackClick);
            AddBarButton(AppResources.Next, ImageUrls.Next, NextClick);

        }

        protected abstract T ConvertId(string id);

        protected virtual void CheckPivot(PivotItem pi)
        {

        }

        protected virtual void RequestMain()
        {
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            if (State.ContainsKey(IndexKey))
            {
                State[IndexKey] = Index;
            }
            else
            {
                State.Add(IndexKey, Index);
            }
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            if (State.ContainsKey(IndexKey))
            {
                Index = (int)State[IndexKey];
            }
            else
            {
                int index;
                int.TryParse(NavigationContext.GetQueryString(IndexKey), out index);
                State.Add(IndexKey, index);
                Index = index;
            }
            if (_idList == null)
            {
                string guid = NavigationContext.GetQueryString(CacheGuidKey);
                if (!string.IsNullOrEmpty(guid)
                    && PhoneApplicationService.Current.State.ContainsKey(guid))
                {
                    _idList = PhoneApplicationService.Current.State[guid] as List<T>;
                }
            }
        }

        protected int Index { get; set; }

        private List<T> _idList;
        protected List<T> IdList
        {
            get
            {
                return _idList;
            }
        }

        protected void NextClick(object sender, EventArgs e)
        {
            CycleIndexTransition trans = new CycleIndexTransition
                {
                    Mode = CycleIndexTransitionMode.Forward
                };
            ITransition transition = trans.GetTransition(this);
            transition.Begin();

        }

        protected void BackClick(object sender, EventArgs e)
        {
            CycleIndexTransition trans = new CycleIndexTransition
                {
                    Mode = CycleIndexTransitionMode.Backward
                };
            ITransition transition = trans.GetTransition(this);
            transition.Begin();

        }


        public static readonly DependencyProperty TriggerIndexProperty =
                                    DependencyPropertyExt.Register<PhoneDetailPage<T>, object>(x => x.TriggerIndex,
                                                                             new PropertyMetadata(null, TriggerIndexChanged));

        public object TriggerIndex
        {
            get
            {
                return GetValue(TriggerIndexProperty);
            }
            set
            {
                SetValue(TriggerIndexProperty, value);
            }
        }

        private static void TriggerIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue != null)
            {
                int index = int.Parse((string)args.NewValue);
                if (index != 0
                    && !args.NewValue.Equals(args.OldValue))
                {
                    PhoneDetailPage<T> page =  obj as PhoneDetailPage<T>;
                    if (page != null)
                    {
                        page.Index += index;
                        if (page.Index < 0)
                        {
                            page.Index = page.IdList.Count - 1;
                        }
                        else if (page.Index >=
                                 page.IdList.Count)
                        {
                            page.Index = 0;
                        }
                        page.ClearRequests();
                        page.RequestMain();
                        page.CheckPivot(page._pivot.SelectedItem as PivotItem);
                    }
                }
            }
        }

        protected virtual void ClearRequests()
        {
        }

        protected static string CacheIdList(List<T> list)
        {
            string guid = Guid.NewGuid().ToString();

            PhoneApplicationService.Current.State.Add(guid, list);

            return guid;
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackKeyPress(e);
            string guid = NavigationContext.GetQueryString(CacheGuidKey);
            if (!string.IsNullOrEmpty(guid)
                && PhoneApplicationService.Current.State.ContainsKey(guid))
            {
                PhoneApplicationService.Current.State.Remove(guid);
            }
        }
    }
}
